package seqList;

import seqList.Exception.EmptyException;
import seqList.Exception.FullException;
import seqList.Exception.IndexOutOfException;

import java.util.Arrays;

public class MyArrayList<T> implements IList<T>{

    T[] array;
    int usedSize;

    private static final int CAPACITY = 10;

    public MyArrayList() {
        this.array = (T[]) new Object[CAPACITY];
    }

    public MyArrayList(int enSureCapacity) {
        this.array = (T[]) new Object[enSureCapacity];
    }

    @Override
    public int size() {
        return this.usedSize;
    }

    private boolean isFull1() {
        return this.usedSize == this.array.length;
    }

    private void isFull2() throws FullException{
        if(this.usedSize == this.array.length) {
            throw new FullException("顺序表已满");
        }

    }

    private void indexOutOf(int pos) throws IndexOutOfException{
        if(pos < 0 || pos > this.usedSize) {
            throw new IndexOutOfException("下标非法");
        }
    }

    private boolean isEmpty1() {
        return this.usedSize == 0;
    }

    private void isEmpty2() throws EmptyException {
        if(this.usedSize == 0) {
            throw new EmptyException("顺序表为空");
        }
    }

    private void grow() {
        this.array = Arrays.copyOf(this.array,2*this.usedSize);
    }

    @Override
    public void add(T t) {
        //如果顺序表满则扩容
        if(isFull1()) {
            grow();
        }

        this.array[this.usedSize] = t;
        this.usedSize++;

    }

    @Override
    public void add(T t, int pos) throws IndexOutOfException,FullException {
        try{
            isFull2();
            indexOutOf(pos);
        }
        catch (FullException | IndexOutOfException e) {
            e.printStackTrace();
        }

        //将元素向后移动
        for(int i = this.usedSize;i>=pos;i--) {
            this.array[i+1] = this.array[i];
        }

        this.array[pos] = t;
        this.usedSize++;

    }

    @Override
    public void remove(int pos) {
        try {
            isEmpty2();
            indexOutOf(pos);
        }
        catch(EmptyException | IndexOutOfException e) {
            e.printStackTrace();
        }

        for (int i = pos; i < this.usedSize; i++) {
            this.array[i] = this.array[i+1];
        }

        this.usedSize--;
    }

    @Override
    public void modify(T t, int pos) {
         try {
             indexOutOf(pos);
         }
         catch (IndexOutOfException e) {
             e.printStackTrace();
         }

         this.array[pos] = t;

    }

    @Override
    public int find(T t) {
        for (int i = 0; i < this.array.length; i++) {
            if(t.equals(this.array[i])) {
                return i;
            }
        }

        return -1;
    }

    @Override
    public String toString() {
        return "MyArrayList{" +
                "array=" + Arrays.toString(array) +
                ", usedSize=" + usedSize +
                '}';
    }

    public void clear() {
        if(isFull1()){
            return;
        }
        for (int i = 0; i < this.usedSize; i++) {
            this.array[i] = null;
        }

        this.usedSize = 0;
    }
}
